package com.ccteam.shared.domain.album

import android.support.v4.media.MediaMetadataCompat
import com.ccteam.fluidmusic.fluidmusic.common.MusicServiceConnectionFlow
import com.ccteam.fluidmusic.fluidmusic.media.extensions.*
import com.ccteam.model.Resource
import com.ccteam.model.album.AlbumVO
import com.ccteam.model.music.BITRATE_NO
import com.ccteam.model.music.MusicVO
import com.ccteam.network.ApiError
import com.ccteam.shared.data.album.AlbumRepository
import com.ccteam.shared.domain.FlowUseCase
import com.ccteam.shared.result.album.AlbumDetailHeaderItem
import com.ccteam.shared.result.album.AlbumDetailMusicItem
import com.ccteam.shared.result.artist.ArtistInfoData
import com.ccteam.shared.utils.ALBUM_QUALITY
import com.ccteam.shared.utils.ARTIST_SEPARATOR
import com.ccteam.shared.utils.getPlaybackStatus
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import javax.inject.Inject

/**
 * @author Xiaoc
 * @since 2021/2/19
 *
 * 专辑详情
 * 传入[Pair<String,String>]
 *     first代表对应专辑详情页的parentId（进行在线音乐的设置）
 *     second代表对应专辑详情页的albumId（进行专辑内容的获取）
 * 返回[AlbumDetailUseCaseResult] 歌曲详情内容
 */
class AlbumDetailUseCase @Inject constructor(
    private val albumRepository: AlbumRepository,
    private val musicServiceConnectionFlow: MusicServiceConnectionFlow
): FlowUseCase<Pair<String, String>, AlbumDetailUseCaseResult>(
    Dispatchers.IO
) {

    override fun execute(parameters: Pair<String,String>): Flow<Resource<AlbumDetailUseCaseResult>> {
        val (parentId,albumId) = parameters

        return albumRepository.getAlbumInfo(albumId).zip(
            albumRepository.getAlbumMusic(albumId)
        ){ albumInfo, albumMusicList ->
            if(albumInfo is Resource.Success && albumMusicList is Resource.Success){
                val result = transformToAlbumInfo(parentId,albumInfo.data,albumMusicList.data)
                if(result != null){
                    Resource.Success(result)
                } else {
                    Resource.Error(ApiError.dataIsNullCode, "数据为空不正确",
                        null)
                }
            } else if(albumInfo is Resource.Error || albumMusicList is Resource.Error){
                // 如果请求来的数据有一项为空不存在，则Error数据直接为null，让界面直接显示错误信息
                Resource.Error(ApiError.serverErrorCode,albumInfo.message ?: albumMusicList.message ?: "未知错误",
                    transformToAlbumInfo(parentId,albumInfo.data,albumMusicList.data))
            } else {
                Resource.Loading(transformToAlbumInfo(parentId,albumInfo.data,albumMusicList.data))
            }
        }
    }

    /**
     * 转换服务端传来的内容为 [AlbumDetailUseCaseResult]
     * 因涉及到在线音乐列表的设置，需要传递parentId
     *
     * @return 如果头部已经为空了，则整个内容返回null
     */
    private fun transformToAlbumInfo(
        parentId: String,
        albumVO: List<AlbumVO>?,
        musicList: List<MusicVO>?
    ): AlbumDetailUseCaseResult?{
        val header = transformToAlbumHeaderItem(albumVO)
        return if(header != null){
            AlbumDetailUseCaseResult(
                    header,transformToAlbumMusicItem(parentId,header,musicList))
        } else {
            null
        }
    }

    private fun transformToAlbumHeaderItem(albumVO: List<AlbumVO>?): AlbumDetailHeaderItem?{
        return if(!albumVO.isNullOrEmpty()){
            AlbumDetailHeaderItem(
                albumVO[0].id,
                albumVO[0].name,
                albumVO[0].imgUrl + ALBUM_QUALITY,
                albumVO[0].artistName,
                albumVO[0].albumYear,
                albumVO[0].introduction,
                albumVO[0].artistId
            )
        } else {
            null
        }
    }

    private fun transformToAlbumMusicItem(
        parentId:String,
        albumInfo: AlbumDetailHeaderItem,
        musicList: List<MusicVO>?): List<AlbumDetailMusicItem>{

        /**
         * 将音乐信息加入到browseTree中以便播放
         */
        musicList?.let {
            val items  = mutableListOf<MediaMetadataCompat>()
            it.forEach { music ->
                // 如果当前音乐没有音源，则不加入到其中
                if(music.maxBitrate == BITRATE_NO || music.url.isNullOrEmpty()){
                     return@forEach
                }
                items.add(
                    MediaMetadataCompat.Builder().apply {
                        id = music.id
                        duration = music.duration
                        title = music.name
                        displayTitle = music.name
                        album = music.albumName
                        displaySubtitle = music.albumName
                        displayDescription = music.artists
                        artist = music.artists
                        albumId = music.albumId
                        trackNumber = music.track.toLong()
                        mediaUri = music.url
                        albumArtUri = albumInfo.albumArtUri
                        displayIconUri = albumInfo.albumArtUri
                    }.build()
                )
            }
            musicServiceConnectionFlow.addOnlineMusicItems(
                parentId = parentId,
                items = items
            )
        }

        /**
         * 这里将数据填入 [AlbumDetailMusicItem]，其中 playable 代表是否可播放，如果maxBitrate是NO，则不可播放
         */
        return musicList?.map {
            /**
             * 分割成ArtistInfoData类型，其中含有歌手信息
             */
            val artistsArray = it.artists.split(ARTIST_SEPARATOR)
            val artistInfo = if(artistsArray.size == it.artistsId.size){
                artistsArray.mapIndexed{ index, artistName ->
                    ArtistInfoData(it.artistsId[index],artistName)
                }
            } else {
                emptyList()
            }
            AlbumDetailMusicItem(it.id,it.artists,it.name,artistInfo,albumInfo.albumId,it.track,
                it.maxBitrate,playable = !it.url.isNullOrEmpty(),
                musicServiceConnectionFlow.nowPlaying.value.getPlaybackStatus(it.id))
        } ?: emptyList()
    }
}

data class AlbumDetailUseCaseResult(
    val albumHeader: AlbumDetailHeaderItem,
    val albumMusicList: List<AlbumDetailMusicItem>
)

